//============================================================================
// Name        : Menu.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <cstring>
#include <sstream>
#include <iomanip>
#include "../Util/Util.h"
#include "../ArchivoDeBloques/ArchivoDeBloques.h"
#include "../Identificadores/Instancia.h"
#include "../ABMsEntidades/ABMBretel.h"
#include "../ABMsEntidades/ABMCopa.h"
#include "../ABMsEntidades/ABMCorpino.h"
#include "../ABMsEntidades/ABMFamilia.h"
#include "../ABMsEntidades/ABMFormador.h"
#include "../ABMsEntidades/ABMMaterial.h"
#include "../ABMsEntidades/ABMTintura.h"
#include "../ABMsEntidades/ABMVentas.h"
#include "../Identificadores/Instancia.h"
#include "ElementoMenu.h"
#include "../Reportes/Reporte.h"

#include <vector>

using namespace std;

const int c_salir = -1;
const bool logMsg = false; //para activar mensajes de debug
//http://mathbits.com/MathBits/CompSci/APstrings/APgetline.htm
string dummy;
ABMCorpino * abmCorpino;
ABMCopa * abmCopa;
ABMFamilia * abmFamilia;
ABMFormador * abmFormador;
ABMMaterial * abmMaterial;
ABMTintura * abmTintura;
ABMVentas * abmVentas;
ABMBretel * abmBretel;

void menu();
void AdministrarEntidades();
vector<string> ListarInstancia(int entidad);
int ExisteIdInstancia (int entidad, int idInstanciaABuscar);

int salir() {
	return c_salir;
}

string nombreEntidad(int codEntidad) {

	ArchivoDeBloques archivo("./src/dat/entidades.dat");
	int cantBloques = archivo.cantBloques;
	//int *pCantBloques =&cantBloques;
	Bloque* bloqueLeido;
	Registro* registroLeido;
	ostringstream temp;

	if (codEntidad <= cantBloques) {
		bloqueLeido = archivo.leerBloque(codEntidad);
		registroLeido = bloqueLeido->obtenerRegistro(1); //obtiene la cabecera de la entidad
		//temp << "  Bloque "<< i << ": " <<(*bloqueLeido).bufferBloque << endl;
		temp << (*registroLeido).buffer;
	} else { //no retorna nada;
		temp.str(std::string()); //retorna vacio
	}

	return temp.str();
}

int opcionChar2int(char opcionChar) {
	int opcion;
	if (opcionChar == 's' || opcionChar == 'S') {
		opcion = salir();
	} else {
		opcion = opcionChar - '0';
		//charoUInt(opcionChar); //hay que ver cuando sea mayor a 10
	}
	return opcion;
}
;

/*
 int opcionChar2int(const char *opcionChar){
 int opcion;
 string str = string(opcionChar);
 if ((str.compare("s") == 0) || (str.compare("S") == 0)) {
 opcion = salir();

 }else{
 opcion= atoi(str.c_str()); //hay que ver cuando sea mayor a 10
 }
 return opcion;
 };
 */

string obtenerNomArchInstancia(int entidad) {

	string nomArchInst;
	nomArchInst = "";
	switch (entidad) {
	case 0:
		nomArchInst = "./src/dat/CORPINO.dat";
		break;
	case 1:
		nomArchInst = "./src/dat/TINTURA.dat";
		break;

	case 2:
		nomArchInst = "./src/dat/BRETEL.dat";
		break;
	case 3:
		nomArchInst = "./src/dat/MATERIAL.dat";
		break;
	case 4:
		nomArchInst = "./src/dat/FORMADOR.dat";
		break;
	case 5:
		nomArchInst = "./src/dat/COPA.dat";
		break;
	case 6:
		nomArchInst = "./src/dat/VENTAS.dat";
		break;
	case 7:
		nomArchInst = "./src/dat/FAMILIA.dat";
		break;

	default:
		break;
	} //fin switch
	return nomArchInst;

}

void AgregarInstancia(int entidad, int idInstancia) {
	cout << "Creando instancia a la entidad.." << nombreEntidad(entidad)
			<< endl;
	ArchivoDeBloques archivo("./src/dat/entidades.dat");
	string nomArchInst = obtenerNomArchInstancia(entidad);

	ArchivoDeBloques archivoInst(nomArchInst);

	vector<ElementoMenu> elementosInstancias;

	Bloque* bloqueLeido;
	Registro* registroLeido;
	ostringstream temp;
	string texto,dummy; //dummy se usa para limpiar antes de cada getline - no usar para llenar variables
	string bufferReg;
	string esObligatorio;
	string longChar;

	int num;
	unsigned int ancho;
	bool esLongCorrecta;

	bloqueLeido = archivo.leerBloque(entidad);
	if (logMsg) {
		cout << "cantidad de registros " << bloqueLeido->cantidadRegistros()
				<< endl;
	};
	//cout <<"Agregando Instancia a la entidad.." << entidad << endl;

	for (unsigned int i = 1; i <= bloqueLeido->cantidadRegistros(); i++) {

		registroLeido = bloqueLeido->obtenerRegistro(i); //obtiene la cabecera de la entidad
		//temp << "  Bloque "<< i << ": " <<(*bloqueLeido).bufferBloque << endl;

		if (i == 1) {
			temp << "Agregando instancia a la entidad "
					<< (*registroLeido).buffer;

		} else if (i == 2) {
			//cout <<"Agregando Instancia a la entidad.. " << (*bloqueLeido).bufferBloque  << endl;
			temp << (*registroLeido).buffer << endl;

		} else {
			//cout << temp ;
			//cin.clear();
			//texto.clear();
			//leo el nombre del campo
			if (logMsg) {
				cout << i;
			}
			cout << "Atributo " << (*registroLeido).buffer;
			//cout << "1." << i <<"."<< (*registroLeido).buffer << "\n";

			string nombrePosibleEntidad = (*registroLeido).buffer;

			i++; //avanzo en el indice
			registroLeido = bloqueLeido->obtenerRegistro(i);
			bufferReg = (*registroLeido).buffer;
			if (bufferReg.compare("S") == 0) {
				cout << " (obligatorio";
				esObligatorio = "S";

			} else {
				cout << " (no obligatorio";
				esObligatorio = "N";
			};
			i++; //avanzo en el indice
			registroLeido = bloqueLeido->obtenerRegistro(i);
			bufferReg = (*registroLeido).buffer;
			if (bufferReg.compare("C") == 0) {

				i++; //avanzo en el indice - lee long del string
				registroLeido = bloqueLeido->obtenerRegistro(i);
				longChar = (*registroLeido).buffer;

				//cout << "de longitud "<< longChar;
				//ingresa por pantalla

				ancho = Util::stringToUint(longChar);
				//cin >> setw(ancho) >> texto;
				if (ancho == 5) { //boolean
					cout << " tipo booleano)" << endl;
					//cin.clear();

					do {
						cout << "Agrega el atributo (S,N): ";
						texto = "";
						getline(cin, texto);
						ElementoMenu elemento;
						elemento.cadena = texto;
						elementosInstancias.push_back(elemento);
					} while (texto.compare("S") != 0 && texto.compare("N") != 0);

				} else if (ancho == 8) { //fecha
					cout << " tipo fecha)" << endl;
					//cin.clear();
					texto = "";
					cout << "ingrese la fecha (formato DD/MM/YY): ";
					getline(cin, texto);
					ElementoMenu elemento;
					elemento.cadena = texto;
					elementosInstancias.push_back(elemento);
				} else {

					cout << " tipo caracter)" << endl;
					esLongCorrecta = false;
					while (!esLongCorrecta) { //
						//cout << "entro al while"<<endl;
						//cin.clear();
						texto = "";
						cout << "ingrese la descripcion: ";
						//std::cin.ignore();
						//cin >> texto;

						getline(cin, texto,'\n');
						if (texto.length() > ancho) {
							cout << "la longitud de " << texto << " es"
									<< texto.length() << ". Maximo=" << ancho
									<< endl;
							cout
									<< "El texto ingresado es mayor al permitido. Vuelva a ingresarlo. "
									<< endl;
						} else if (esObligatorio.compare("S") == 0
								&& texto == "\0") {

							cout
									<< "El campo es obligatorio. No ha ingresado ningun texto. Vuelva a ingresarlo. "
									<< endl;

						} else {
							cout << "El texto ingresado es " << texto << endl;
							esLongCorrecta = true;
							ElementoMenu elemento;
							elemento.cadena = texto;
							elementosInstancias.push_back(elemento);
						}

					} //fin while
				}
			} else if (bufferReg.compare("X") == 0) {
				cout << " tipo entidad)" << endl;
				cout << " Estas son las entidades creadas:" << endl;
				//listar instancias de entidades.
				vector<string> instancias;
				Instancia ids = Instancia();
				int idEntidadRelacion = -1;

				if (nombrePosibleEntidad.compare("CORPINO") == 0) {
					instancias = abmCorpino->listar();
					idEntidadRelacion = 0;
				} else if (nombrePosibleEntidad.compare("TINTURA") == 0) {
					instancias = abmTintura->listar();
					idEntidadRelacion = 1;
				} else if (nombrePosibleEntidad.compare("BRETEL") == 0) {
					instancias = abmBretel->listar(ids.obtenerIdBretel());
					idEntidadRelacion = 2;
				} else if (nombrePosibleEntidad.compare("MATERIAL") == 0) {
					instancias = abmMaterial->listar(ids.obtenerIdMaterial());
					idEntidadRelacion = 3;
				} else if (nombrePosibleEntidad.compare("FORMADOR") == 0) {
					instancias = abmFormador->listar(ids.obtenerIdFormador());
					idEntidadRelacion = 4;
				} else if (nombrePosibleEntidad.compare("COPA") == 0) {
					instancias = abmCopa->listar(ids.obtenerIdCopa());
					idEntidadRelacion = 5;
				} else if (nombrePosibleEntidad.compare("VENTAS") == 0) {
					instancias = abmVentas->listar();
					idEntidadRelacion = 6;
				} else if (nombrePosibleEntidad.compare("FAMILIA") == 0) {
					instancias = abmFamilia->listar();
					idEntidadRelacion = 7;
				}

				for (unsigned int i = 0; i < instancias.size(); i++) {
					cout << instancias.at(i) << endl;
				}

				//ingresa por pantalla
				//cin >> texto;
				//getline(cin,dummy);
				getline(cin, texto);
				num = Util::stringToInt(texto);

				int existe=ExisteIdInstancia (idEntidadRelacion, num);

				if (existe!=0){
					cout << "La instancia " << num << " no existe."<<endl;
					return;
				}else {

				ElementoMenu elemento;
				elemento.entero = num;

				elementosInstancias.push_back(elemento);
				}
			} else if (bufferReg.compare("E") == 0) {
				cout << " tipo entero)" << endl;
				//cin >> texto;
				//getline(cin, dummy);
				getline(cin, texto);
				num = Util::stringToInt(texto);
				ElementoMenu elemento;
				elemento.entero = num;
				cout << "ud ingreso: " << num << endl;

				elementosInstancias.push_back(elemento);
			}

			//graba en el archivo de instancias
			//Instancia::Agregar();

			if (logMsg) {
				cout << "siguiente atributo" << endl;
			}

		}

	}
	Instancia ids = Instancia();
	if (entidad == 0) {
		string descripcion = elementosInstancias.at(0).cadena;
		string contorno = elementosInstancias.at(1).cadena;
		bool contornoBool = (contorno.compare("S") == 0);
		int precio = elementosInstancias.at(2).entero;
		int material = elementosInstancias.at(3).entero;
		int bretel = elementosInstancias.at(4).entero;
		int copa = elementosInstancias.at(5).entero;
		int familia = elementosInstancias.at(6).entero;
		int tintura = elementosInstancias.at(7).entero;

		if (idInstancia == -1) {
			abmCorpino->alta(ids.obtenerIdCorpinio(), descripcion, contornoBool,
					precio, material, bretel, copa, familia, tintura);
			ids.incrementarIdCorpinio();
		} else {
			abmCorpino->modificacion(idInstancia, descripcion, contornoBool,
					precio, material, bretel, copa, familia, tintura);
		}
	} else if (entidad == 1) {
		string descripcion = elementosInstancias.at(0).cadena;
		string colorestampa = elementosInstancias.at(1).cadena;
		bool colorestampaBool = (colorestampa.compare("S") == 0);

		if (idInstancia == -1) {
			abmTintura->alta(ids.obtenerIdTintura(), descripcion,
					colorestampaBool);
			ids.incrementarIdTintura();
		} else {
			abmTintura->modificacion(idInstancia, descripcion,
					colorestampaBool);
		}
	} else if (entidad == 2) {
		string descripcion = elementosInstancias.at(0).cadena;

		if (idInstancia == -1) {
			abmBretel->alta(ids.obtenerIdBretel(), descripcion);
			ids.incrementarIdBretel();
		} else {
			abmBretel->modificacion(idInstancia, descripcion);
		}
	} else if (entidad == 3) {
		string descripcion = elementosInstancias.at(0).cadena;
		if (idInstancia == -1) {
			abmMaterial->alta(ids.obtenerIdMaterial(), descripcion);
			ids.incrementarIdMaterial();
		} else {
			abmMaterial->modificacion(idInstancia, descripcion);

		}
	} else if (entidad == 4) {
		string descripcion = elementosInstancias.at(0).cadena;

		if (idInstancia == -1) {
			abmFormador->alta(ids.obtenerIdFormador(), descripcion);
			ids.incrementarIdFormador();
		} else {
			abmFormador->modificacion(idInstancia, descripcion);

		}
	} else if (entidad == 5) {
		int formador = elementosInstancias.at(0).entero;
		string armado = elementosInstancias.at(1).cadena;
		bool armadoBool = (armado.compare("S") == 0);
		string aro = elementosInstancias.at(2).cadena;
		bool aroBool = (aro.compare("S") == 0);

		if (idInstancia == -1) {
			abmCopa->alta(ids.obtenerIdCopa(), formador, armadoBool, aroBool);
			ids.incrementarIdCopa();
		} else {
			abmCopa->modificacion(idInstancia, formador, armadoBool, aroBool);

		}
	} else if (entidad == 6) {
		int corpinio = elementosInstancias.at(0).entero;
		string fecha = elementosInstancias.at(1).cadena;
		int precio = elementosInstancias.at(2).entero;
		string cliente = elementosInstancias.at(3).cadena;

		if (idInstancia == -1) {
			abmVentas->alta(ids.obtenerIdVentas(), cliente, corpinio, precio,
					fecha);
			ids.incrementarIdVentas();
		} else {
			abmVentas->modificacion(idInstancia, cliente, corpinio, precio,
					fecha);
		}
	} else if (entidad == 7) {
		string descripcion = elementosInstancias.at(0).cadena;
		string fabricante = elementosInstancias.at(1).cadena;
		int precio = elementosInstancias.at(2).entero;
		if (idInstancia == -1) {
			abmFamilia->alta(ids.obtenerIdFamilia(), descripcion, fabricante,
					precio);
			ids.incrementarIdFamilia();
		} else {
			abmFamilia->modificacion(idInstancia, descripcion, fabricante,
					precio);
		}
	}

}

void ModificarInstancia(int entidad) {
	cout << "Modificando Instancia.." << endl;
	string nomArchInst = obtenerNomArchInstancia(entidad);
	Instancia ids = Instancia();

	vector<string> instancias;
	if (entidad == 0) {
		instancias = abmCorpino->listar();
	} else if (entidad == 1) {
		instancias = abmTintura->listar();
	} else if (entidad == 2) {
		instancias = abmBretel->listar(ids.obtenerIdBretel());
	} else if (entidad == 3) {
		instancias = abmMaterial->listar(ids.obtenerIdMaterial());
	} else if (entidad == 4) {
		instancias = abmFormador->listar(ids.obtenerIdFormador());
	} else if (entidad == 5) {
		instancias = abmCopa->listar(ids.obtenerIdCopa());
	} else if (entidad == 6) {
		instancias = abmVentas->listar();
	} else if (entidad == 7) {
		instancias = abmFamilia->listar();
	}

	for (unsigned int i = 0; i < instancias.size(); i++) {
		cout << instancias.at(i) << endl;
	}

	cout << "Seleccione el id de la Instancia que desea modificar" << endl;
	string texto;
	cin >> texto;
	getline(cin,dummy);//limpia el buffer
	int id = Util::stringToInt(texto);

	int existe=ExisteIdInstancia (entidad, id);

	if (existe==0){
		//cout << "La instancia existe"<<endl;
		AgregarInstancia(entidad, id);
	}else {
		cout << "La instancia " << id << " no existe"<<endl;
	}
}

void EliminarInstancia(int entidad) {
	cout << "Eliminando Instancias.." << endl;
	string nomArchInst = obtenerNomArchInstancia(entidad);
	string texto;
	unsigned int idInstancia;

	ListarInstancia(entidad);
	texto = "";
	cout << "ingrese el ID de la instancia a eliminar: ";
	cin >> texto;
	getline(cin,dummy);//limpia el buffer
	idInstancia = Util::stringToUint(texto);

	if (logMsg) {
		cout << "ud ingreso: " << idInstancia << endl;
	};
	int existe=ExisteIdInstancia (entidad, idInstancia);

	if (existe!=0){
		cout << "La instancia " << idInstancia << " no existe."<<endl;

	}else {

		if (entidad == 0) {
			abmCorpino->baja(idInstancia);
		} else if (entidad == 1) {
			abmTintura->baja(idInstancia);
		} else if (entidad == 2) {
			abmBretel->baja(idInstancia);
		} else if (entidad == 3) {
			abmMaterial->baja(idInstancia);
		} else if (entidad == 4) {
			abmFormador->baja(idInstancia);
		} else if (entidad == 5) {
			abmCopa->baja(idInstancia);
		} else if (entidad == 6) {
			abmVentas->baja(idInstancia);
		} else if (entidad == 7) {
			abmFamilia->baja(idInstancia);
		}
	};
}
;

void EliminarTodasInstancias(int entidad) {
	cout << "Eliminando todas las instancias.." << endl;
	vector<string> instancias = ListarInstancia(entidad);

	for (int i = 0; i < instancias.size(); i++) {
		string instancia = instancias.at(i);
		int pos = instancia.find(";");
		string idString = instancia.substr(0, pos);
		int id = Util::stringToInt(idString);

		if (entidad == 0) {
			abmCorpino->baja(id);
		} else if (entidad == 1) {
			abmTintura->baja(id);
		} else if (entidad == 2) {
			abmBretel->baja(id);
		} else if (entidad == 3) {
			abmMaterial->baja(id);
		} else if (entidad == 4) {
			abmFormador->baja(id);
		} else if (entidad == 5) {
			abmCopa->baja(id);
		} else if (entidad == 6) {
			abmVentas->baja(id);
		} else if (entidad == 7) {
			abmFamilia->baja(id);
		}
	}
}
vector<string> ListarInstancia2(int entidad) {
	if (logMsg) {
	cout << "Listando Instancia2.." << endl;
	};
	string nomArchInst = obtenerNomArchInstancia(entidad);
	Instancia ids = Instancia();

	vector<string> instancias;
	if (entidad == 0) {
		instancias = abmCorpino->listar();
	} else if (entidad == 1) {
		instancias = abmTintura->listar();
	} else if (entidad == 2) {
		instancias = abmBretel->listar(ids.obtenerIdBretel());
	} else if (entidad == 3) {
		instancias = abmMaterial->listar(ids.obtenerIdMaterial());
	} else if (entidad == 4) {
		instancias = abmFormador->listar(ids.obtenerIdFormador());
	} else if (entidad == 5) {
		instancias = abmCopa->listar(ids.obtenerIdCopa());
	} else if (entidad == 6) {
		instancias = abmVentas->listar();
	} else if (entidad == 7) {
		instancias = abmFamilia->listar();
	}
	return instancias;

}
;

vector<string> ListarInstancia(int entidad) {
	cout << "Listando Instancia.." << endl;
	string nomArchInst = obtenerNomArchInstancia(entidad);
	Instancia ids = Instancia();

	vector<string> instancias;
	if (entidad == 0) {
		instancias = abmCorpino->listar();
	} else if (entidad == 1) {
		instancias = abmTintura->listar();
	} else if (entidad == 2) {
		instancias = abmBretel->listar(ids.obtenerIdBretel());
	} else if (entidad == 3) {
		instancias = abmMaterial->listar(ids.obtenerIdMaterial());
	} else if (entidad == 4) {
		instancias = abmFormador->listar(ids.obtenerIdFormador());
	} else if (entidad == 5) {
		instancias = abmCopa->listar(ids.obtenerIdCopa());
	} else if (entidad == 6) {
		instancias = abmVentas->listar();
	} else if (entidad == 7) {
		instancias = abmFamilia->listar();
	}

	for (unsigned int i = 0; i < instancias.size(); i++) {
		cout << instancias.at(i) << endl;
	}

	return instancias;

}
;

int ExisteIdInstancia (int entidad, int idInstanciaABuscar){
	Instancia ids = Instancia();
	vector<string> instancias = ListarInstancia2(entidad);
	int pos,id,existe;
	string idString;

	if (logMsg){
		cout << "buscando id " << idInstanciaABuscar;
	}

	existe = -1;
	for (unsigned int i = 0; i < instancias.size(); i++) {
		idString="";
		string instancia = instancias.at(i);
		pos = instancia.find(";");
		idString = instancia.substr(0, pos);
		id = Util::stringToInt(idString);

		if (id == idInstanciaABuscar){
			existe=0;//existe la instancia
			break;
		}
		existe=-1; //no encontro el ID
	}

	return existe;

}

void BuscarInstanciaPorID(int entidad) {
	cout << "Buscar Instancia por ID.." << endl;
	string texto;
	int existe;
	int idInstancia;

	cout << "Ingrese el Id de la instancia de " << nombreEntidad (entidad) << endl;
	cin >> texto;
	getline(cin,dummy);//limpia el buffer
	idInstancia = Util::stringToInt(texto);
	cout << "Ud. ingreso " << idInstancia << endl;

	existe=ExisteIdInstancia (entidad, idInstancia);

	if (existe==0){
		cout << "La instancia existe"<<endl;
	}else {
		cout << "La instancia no existe"<<endl;

	}


}
;
void AdmIndicesSecundarios() {
	cout << "Administrar Indices Secundario.." << endl;

}
;

string ListarEntidades(int* maxElem) {

	ArchivoDeBloques archivo("./src/dat/entidades.dat");
	int cantBloques = archivo.cantBloques;
	//int *pCantBloques =&cantBloques;
	Bloque* bloqueLeido;
	Registro* registroLeido;
	ostringstream temp;

	temp.str(std::string());

	for (int i = 0; i < cantBloques; i++) //no esta grabando la cantidad de Bloques
			{
		if (i == 0) {
			temp << "entidades disponibles: " << cantBloques << endl;
		};
		bloqueLeido = archivo.leerBloque(i);
		registroLeido = bloqueLeido->obtenerRegistro(1); //obtiene la cabecera de la entidad
		//temp << "  Bloque "<< i << ": " <<(*bloqueLeido).bufferBloque << endl;
		temp << "1." << i << "." << (*registroLeido).buffer << "\n";
		//cout << "1." << i <<"."<< (*registroLeido).buffer << "\n";
	}
	*maxElem = cantBloques;
	//listaEntidades = temp.str();
	return temp.str();
	//for(unsigned int x=0;x<4;x++){
	//	cout<<"Bloque: "<<x<<"  :  "<<archivo.leerBloque(x)->bufferBloque<<endl;
	//}

	/*
	 Bloque* bloqueLeido = archivo.leerBloque(0);
	 cout << (*bloqueLeido).bufferBloque << endl;
	 bloqueLeido = archivo.leerBloque(1);
	 cout << (*bloqueLeido).bufferBloque << endl;
	 bloqueLeido = archivo.leerBloque(2);
	 cout << (*bloqueLeido).bufferBloque << endl;
	 */
}

void SeleccionarAccion(int entidad) {
	int opcion;
	char opcionChar;
	do {
		//system("clear");
		do {
			system("clear");
			cout << "\tADMINISTRADOR DE ENTIDAD " << nombreEntidad(entidad)
					<< endl;
			cout << "1.2.x Seleccionar Accion" << endl;
			cout << "1.2.1.Agregar Instancia" << endl;
			cout << "1.2.2.Modificar Instancia" << endl;
			cout << "1.2.3.Eliminar Instancia" << endl;
			cout << "1.2.4.Listar Instancia" << endl;
			cout << "1.2.5.Eliminar Instancias" << endl;
			cout << "1.2.s.Volver " << endl;
			cout << "  opcion: ";
			cin >> opcionChar;
			getline(cin,dummy);//limpia el buffer
			opcion = opcionChar2int(opcionChar);
			if (logMsg) {
				cout << "ud ingreso " << opcion << endl;
			}
		} while ((opcion < 1 && opcion > 6) && opcion != salir());

		switch (opcion) {
		case 1:
			AgregarInstancia(entidad, -1);
			break;
		case 2:
			ModificarInstancia(entidad);
			break;
		case 3:
			EliminarInstancia(entidad);
			break;
		case 4:
			ListarInstancia(entidad);
			break;
		case 5:
			EliminarTodasInstancias(entidad);
			break;
		case 6:
			BuscarInstanciaPorID (entidad);
			break;
		case c_salir:
			continue; //volver atras
			//case 9: AdministrarEntidades(); break; //volver atras
		default:
			cout << "la opcion ingresada es incorrecta" << endl;
		} //fin switch
	} while (opcion != salir());

}
;
//SeleccionarAccion

void AdministrarEntidades() {
	int opcion;
	char opcionChar;
	string listaEntidades; //lista de entidades
	int maxCantEntidades = 0;
	listaEntidades = ListarEntidades(&maxCantEntidades); //devuelve maxima cantidad de bloques

	do {
		//system("clear");

		do {
			system("clear");
			//cout << "opcion a2" << opcion;
			opcion = salir(); //inicializo

			cout << "\tADMINISTRADOR DE ENTIDADES" << endl;
			cout << "1.x.Seleccionar Entidad" << endl;
			cout << listaEntidades;
			cout << "1.s.Volver " << endl;
			cout << "  opcion: ";

			cin >> opcionChar;
			getline(cin,dummy); //limpia el buffer
			opcion = opcionChar2int(opcionChar);
			cout << "ud ingreso " << opcion << endl;

			if (logMsg) {
				cout << "maxCE" << maxCantEntidades;
			};
		} while ((opcion < -1 && opcion > maxCantEntidades - 1)
				&& opcion != salir());

		//cout << "opcion b2" << opcion;
		//switch(opcion){
		//	    case 1: SeleccionarAccion(); break;
		//	    case 0: continue; //menu(); break;
		//	    default : cout << "la opcion ingresada es incorrecta" <<endl;
		//} //fin switch
		if (opcion == salir()) {
			continue;
			break;
		} else if (opcion > -1 && opcion < maxCantEntidades) {
			SeleccionarAccion(opcion); //opcion = entidad seleccionada
			break;
		} else {
			cout << "opcion incorrecta" << endl;
		}

	} while (opcion != salir());

}

void listarReportes() {
	int opcion;
	char opcionChar;

	do {
		//system("clear");

		do {
			system("clear");
			//cout << "opcion a2" << opcion;
			opcion = salir(); //inicializo

			cout << "\tListado de Reportes" << endl;
			cout << "2.x.Seleccionar Reporte" << endl;

			cout << "2.1 Cantidad de productos por Fabricante"<< endl;
			cout << "2.2 Cantidad de productos por Familia"<< endl;
			cout << "2.3 Cantidad de productos por Tintura"<< endl;
			cout << "2.4 Listar productos por Fabricante"<< endl;
			cout << "2.5 Listar productos por Familia"<< endl;
			cout << "2.6 Listar productos por Tintura"<< endl;
			cout << "2.7 Listar productos por Partes"<< endl;
			cout << "2.8 Listado de Ventas por fecha"<< endl;
			cout << "2.9 Listado de Stock (actual)"<< endl;
			cout << "2.s.Volver " << endl;

			cout << "  opcion: ";

			cin >> opcionChar;
			getline(cin,dummy); //limpia el buffer
			opcion = opcionChar2int(opcionChar);
			cout << "ud ingreso " << opcion << endl;


		} while ((opcion < 1 && opcion > 9) && opcion != salir());

			switch (opcion) {
			case 1:
				Reporte::cantCopiniosPorFabricante(abmCorpino,abmFamilia);
				break;
			case 2:
				Reporte::cantCopiniosPorFamilia(abmCorpino,abmFamilia);
				break;
			case 3:
				Reporte::cantCopiniosPorTintura(abmCorpino,abmTintura);
				break;
			case 4:
				Reporte::listarCorpiniosPorFabricante(abmCorpino,abmFamilia);
				break;
			case 5:
				Reporte::listarCorpiniosPorFamilia(abmCorpino,abmFamilia);
				break;
			case 6:
				Reporte::listarCorpiniosPorTintura(abmCorpino,abmTintura);
				break;
			case 7:
				Reporte::listarCorpiniosPorPartes(abmCorpino,abmCopa,abmBretel,abmFormador);
				break;
			case 8:
				Reporte::listarVentasPorFecha(abmVentas,abmCorpino);
				break;
			case 9:
				Reporte::listadoDeStock(abmVentas,abmCorpino);
				break;
			case c_salir:
				continue; //volver atras

			default:
				cout << "la opcion ingresada es incorrecta" << endl;
				break;
			} //fin switch

	} while (opcion != salir());

}

//AdministrarEntidades

void menu() {

	//Inicializa los abm
	abmCorpino = new ABMCorpino("./src/dat/CORPINO.dat", 95);
	abmCopa = new ABMCopa("./src/dat/COPA.dat", 95);
	abmFamilia = new ABMFamilia("./src/dat/FAMILIA.dat", 95);
	abmFormador = new ABMFormador("./src/dat/FORMADOR.dat", 95);
	abmMaterial = new ABMMaterial("./src/dat/MATERIAL.dat", 95);
	abmTintura = new ABMTintura("./src/dat/TINTURA.dat", 95);
	abmVentas = new ABMVentas("./src/dat/VENTAS.dat", 95);
	abmBretel = new ABMBretel("./src/dat/BRETEL.dat", 95);

	int opcion;
	bool finProg = false;
	char opcionChar;
	do {
		//system("clear");
		do {
			//cout << "opcion a1 " << opcion;
			system("clear");
			cout << "\tADMINISTRADOR DE ENTIDADES" << endl;
			cout << "1.Administrar Entidades" << endl;
			cout << "2.Listar Reportes" << endl;
			cout << "s.salir" << endl;
			cout << "  opcion: ";
			cin >> opcionChar;
			getline(cin,dummy); //limpia el buffer
			opcion = opcionChar2int(opcionChar);

			cout << "ud ingreso " << opcion << endl;

		} while (opcion != salir() && opcion != 1 && opcion != 2);
		//cout << "opcion b1 " << opcion;

		switch (opcion) {
		case 1:
			AdministrarEntidades();
			break;
		case 2:
			listarReportes();
			break;
		case c_salir:
			finProg = true;
			break;
		default:
			cout << "la opcion ingresada es incorrecta" << endl;
			break;
		} //fin switch
	} while (finProg == false);

	//return 0;

}
/*
 int main (){
 menu();
 return 0;
 }
 */

